package client

const (
	address  = "modbus.rtu.com_name"
	parity   = "modbus.rtu.parity"
	baudRate = "modbus.rtu.baud_rate"
	dataBits = "modbus.rtu.data_bits"
	stopBits = "modbus.rtu.stop_bits"

	host = "modbus.tcp.address"
	port = "modbus.tcp.port"

	timeOut = "modbus.time_out"
	slaveId = "modbus.slaveId"
)

// Type ClientType modbus客户端类型
type Type string

const (
	//RtuClient RTU客户端
	RtuClient Type = "RTU"
	//TcpClient TCP客户端
	TcpClient Type = "TCP"
)

// Api Modbus Client接口
type Api interface {
	// 连接操作

	//Open 打开连接
	//配置:
	//	"modbus.time_out"		: 超时时间
	//rtu需要配置:
	//	 "modbus.rtu.com_name"  : 串口名称
	//   "modbus.rtu.parity"    : 奇偶校验 N O E
	//   "modbus.rtu.baud_rate" : 波特率
	//   "modbus.rtu.data_bits" : 数据位
	//   "modbus.rtu.stop_bits" : 停止位
	//tcp需要配置:
	//	 "modbus.tcp.address"	: IP地址
	//   "modbus.tcp.port"		: 端口

	Open(config map[string]interface{}) error
	//Close 关闭连接
	Close()

	// SetSlaveID 设置SlaveID
	SetSlaveID(slaveID byte)

	//ReadCoils 读1到2000的线圈状态,
	//功能码:0x01
	//参数:
	//	address 地址
	//	quantity 数量
	//返回:
	//  Byte count            : 1 byte
	//  Coil status           : N* bytes (=N or N+1)
	ReadCoils(address, quantity uint16) (results []byte, err error)

	//ReadDiscreteInputs 读取1到2000的离散输入值
	// 功能码:0x02
	//参数:
	//	address : 地址 2 字节
	//	quantity: 数量 2 字节
	//返回:
	//  Byte count            : 1 byte
	//  Input status          : N* bytes (=N or N+1)
	ReadDiscreteInputs(address, quantity uint16) (results []byte, err error)
	//WriteSingleCoil 向线圈写单个开关量输入并返回
	//  功能码:0x05
	//参数:
	//	address 地址
	//	value 	写入值
	WriteSingleCoil(address, value uint16) (results []byte, err error)

	//WriteMultipleCoils 写多个线圈
	// 功能码:0x0F
	//参数:
	//	address : 地址 2 字节
	//	quantity: 数量 2 字节
	//  value   : 值
	WriteMultipleCoils(address, quantity uint16, value []byte) (results []byte, err error)

	// 16-bit access

	//ReadInputRegisters 读1-125寄存器
	// 功能码:0x04
	//参数:
	//	address : 地址 2 字节
	//	quantity: 数量 2 字节
	ReadInputRegisters(address, quantity uint16) (results []byte, err error)
	//ReadHoldingRegisters 读保持寄存器
	// 功能码:0x04
	//参数:
	//参数:
	//	address : 地址 2 字节
	//	quantity: 数量 2 字节
	ReadHoldingRegisters(address, quantity uint16) (results []byte, err error)
	// WriteSingleRegister
	//   功能码:0x06
	//参数:
	//	address :   2 bytes 地址
	//	value	:   2 bytes 值
	WriteSingleRegister(address, value uint16) (results []byte, err error)
	// WriteMultipleRegisters 写多个寄存器(1-123)
	// 功能码:0x10
	//参数:
	//	address : 起始地址 2 字节
	//  quantity: 写入数量 2 字节
	//	value	: 值      N 字节
	WriteMultipleRegisters(address, quantity uint16, value []byte) (results []byte, err error)
	// ReadWriteMultipleRegisters 同时读写寄存器,返回读寄存器值
	// 功能码:0x17
	//参数:
	//	  readAddress:  2 bytes		读起始地址
	//	 readQuantity:  2 bytes		读数量
	//	 writeAddress:  2 bytes		写起始地址
	//	writeQuantity:  2 bytes		写数量
	//	        value:  N * byte	写入寄存器的值
	ReadWriteMultipleRegisters(readAddress, readQuantity, writeAddress, writeQuantity uint16, value []byte) (results []byte, err error)

	//MaskWriteRegister 屏蔽写寄存器
	//功能码:0x16
	//参数:
	//	address:  2 bytes		起始地址
	//	andMask:  2 bytes		与操作
	//	 orMask:  2 bytes		或操作
	MaskWriteRegister(address, andMask, orMask uint16) (results []byte, err error)
	//ReadFIFOQueue reads the contents of a First-In-First-Out (FIFO) queue
	// of register in a remote device and returns FIFO value register.
	ReadFIFOQueue(address uint16) (results []byte, err error)
}

// CreateClient 获取客户端
//
//	clientType:TCP,RTU,其他将返回nil
func CreateClient(clientType Type) Api {
	if clientType == TcpClient {
		return new(ModbusTCP)
	} else if clientType == RtuClient {
		return new(ModbusRTU)
	}
	return nil
}
